/**
Program: PageRank.java
Description: Generate the link matrix for use in Page Rank
Date: 02/20/2001
Developer: Ullas Nambiar

 **/

package qy.course.cse494.web;
//import com.lucene.index.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;
import java.util.Vector;

import qy.course.cse494.util.UtilCenter;

/** Extract the Link Matrix that has been generated by LinkGen
 Provides functions outLinks and Citations. outLinks takes as input a filename and returns how many other pages in the stored
 repository it points to. Method citations accepts the fileName and returns a Vector containing fileNames of Files in the
repository that cite the given file.
 */

public class WebLinksExtractor 
{
    Hashtable<Integer, Vector<Integer>> _web_forword_links = new Hashtable<Integer, Vector<Integer>>();
    Hashtable<Integer, Vector<Integer>> _web_back_links = new Hashtable<Integer, Vector<Integer>>();

    Set<Integer> _web_page_set = new HashSet<Integer>();

    /** Constructor takes as input the Directory name where files are stored and Filename where the LinkMatrix generated by
        LinkGen is stored. Loads the datastructures for use by other methods*/
    public WebLinksExtractor(String matrixFile)
    {
        // load the arraylists with the files and the links they point to
        try
        {
            FileReader fread = new FileReader(matrixFile);
            BufferedReader in = new BufferedReader(fread);
            String sin = in.readLine();
            while(sin != null)
            {
            	// extract the two separte lists
            	String spointer = sin.substring(0,sin.indexOf(":"));
            	sin = sin.substring(sin.indexOf("[")+1,sin.indexOf("]"));
            	//hashids.put(spointer,sin);
            	int key = Integer.parseInt(spointer);
            	Vector<Integer> links_set = UtilCenter.ParseMultiInputInteger(sin, "[-]?\\d+");
            	
            	_web_forword_links.put(key, links_set);
            	_web_page_set.add(key);
            	_web_page_set.addAll(links_set);
            	//
                sin = in.readLine();
            }
            in.close();
            fread.close();
        }catch(FileNotFoundException e1)
        {
        	e1.printStackTrace();
        }catch(IOException e2)
        {
        	e2.printStackTrace();
        }
        
        return;
    }

    public Set<Integer> get_web_pages_set()
    {
    	return _web_page_set;
    }
    
    /** Returns a count of files pointed to by the given FileName*/
    public int  outLinks(int file_name_code)
    {
    	return _web_forword_links.get(file_name_code) == null ? 0 : _web_forword_links.get(file_name_code).size();
    }
    
    /** Returns a list of files/URLs to which the given filename/URL points to */
    public Vector<Integer> LinksTo(int file_name_code)
    {
    	return _web_forword_links.get(file_name_code) == null ? new Vector<Integer>() : _web_forword_links.get(file_name_code);
    }
    
    
    /** Returns a list of files/URLs that point to the given file/URL */
    public Vector<Integer> CitationsBy(int file_name_code)
    {
    	if(_web_back_links.contains(file_name_code))
    	{
    		return _web_back_links.get(file_name_code);
    	}
    	//
    	Vector<Integer> back_link_list = new Vector<Integer>();
    	for(Integer cur_code : _web_forword_links.keySet())
    	{
    		if(_web_forword_links.get(cur_code).contains(file_name_code))
    		{
    			back_link_list.add(cur_code);
    		}
    	}
    	_web_back_links.put(file_name_code, back_link_list);
    	return back_link_list;
    }
    
    /** Demonstrates how the various files should be generated and prints the Citations and OutLinks for the first 6
        files in the  directory. This program should be invoked as :            java LinkExtract "Directory_FilesStored" "LinkMatrixFile". Unless changed Link Matrix File is called "Hashedlinks" */
    public static void main(String[] args)
    {
        WebLinksExtractor lextract;
        
        lextract = new WebLinksExtractor("data/Hashedlinks4");

        File opendirectory;
        String repository = "data/result3";
        String filelist[] = {"a","b"};
        
        opendirectory = new File(repository);
        if(opendirectory.isDirectory())
        {
             filelist = opendirectory.list();
             Arrays.sort(filelist);
        }

        
        System.out.println("The size of db is:" + filelist.length);
           for(int ifi =0 ; ifi < 6 ;ifi++)
           {
        	   int flname_hashcode = filelist[ifi].hashCode();
               //System.out.println(flname);
               int flout = lextract.outLinks(flname_hashcode);
               Vector pointsTo =  lextract.LinksTo(flname_hashcode);
               Vector pointedby = lextract.CitationsBy(flname_hashcode);
               System.out.println(filelist[ifi]+"::");
               for(int ipto = 0; ipto < pointsTo.size(); ipto ++)
            	   System.out.println("\n Points to: " + pointsTo.get(ipto));
               for(int pto =0; pto < pointedby.size();pto++)
            	   System.out.println("\n Pointed by: " + pointedby.get(pto));
           }
        return;
    }

}





